using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using eee.Sheffield.PZ.Imaging.ImageFilter;
using eee.Sheffield.PZ.Imaging;

namespace eee.Sheffield.PZ.QAAS
{
    public partial class GVFFilterControl : FilterControl//, IFilterControl
    {
        #region Fields
        //private string _flag = "GVF Filter";
        private string _centreLineImageFileName = "";
        #endregion

        #region Properties
        //public override string Flag { get { return _flag; } }
        public string CentreLineImageFileName { set { _centreLineImageFileName = value; } }
        #endregion

        #region Constructor
        public GVFFilterControl()
        {
            InitializeComponent();
            _flag = "GVF Filter";
        } 

        public GVFFilterControl(MainForm mainForm, ImageDoc imageDoc) : base(mainForm, imageDoc)
        {
            InitializeComponent();
            _flag = "GVF Filter";
        }
        #endregion
        
        #region Constructor
        public override void Reload()
        {
            _centreLineImageFileName = "";
        }
        #endregion

        #region Botton Events
        /// <summary>
        /// Gradient Vector Field fields
        /// </summary>
        
        private void buttonApply_Click(object sender, EventArgs e)
        {
            // GVF
            GVFReturnType returnType = GVFReturnType.GVFMagnitude;
            string GVFImageTitle = "";
            if (radioButtonUMagnitude.Checked)
            {
                returnType = GVFReturnType.UMagnitude;
                GVFImageTitle = "GVF |u|";
            }
            if (radioButtonGVFMagnitude.Checked)
            {
                returnType = GVFReturnType.GVFMagnitude;
                GVFImageTitle = "|GVF|";
            }
            if (radioButtonVMagnitude.Checked)
            {
                returnType = GVFReturnType.VMagnitude;
                GVFImageTitle = "GVF |v|";
            }

            double sigma = Convert.ToDouble(textBoxSigma.Text);
            double mu = Convert.ToDouble(textBoxMu.Text);
            Bitmap srcImage = _imageDoc.Image;

            GradientVectorFlow filter = new GradientVectorFlow(sigma, mu);
            filter.GVFReturnType = returnType;
            Bitmap copySrcImage = (Bitmap)srcImage.Clone();
            eee.Sheffield.PZ.Imaging.Image.StandardizeImageTo8bbpIndexed(ref copySrcImage);
            Bitmap dstImage = filter.ApplyGraylevelImageFilter(copySrcImage);

            // save V, U, and VectorMagnitude
            filter.WriteFileV("GVFV.txt");
            filter.WriteFileU("GVFU.txt");
            filter.WriteFileVectorMagnitude("GVFVectorMagnitude.txt");

            if (dstImage.PixelFormat == System.Drawing.Imaging.PixelFormat.Format8bppIndexed)
                eee.Sheffield.PZ.Imaging.Image.GenerateGraylevelPalette(ref dstImage);
            _log = filter.LogText;
            ShowImage(dstImage, GVFImageTitle);
            Log(_log);

            // Gs value map            
            #region Gs value map
            if (checkBoxGs.Checked)
            {
                double gt = Convert.ToDouble(textBoxGt.Text);
                if (_centreLineImageFileName == "")
                {
                    if (openFileDialogCentreLineImageFile.ShowDialog() == DialogResult.OK)
                    {
                        _centreLineImageFileName = openFileDialogCentreLineImageFile.FileName;
                    }
                }
                if (_centreLineImageFileName != "")
                {
                    Bitmap GsValueImage = DoGsValue(filter, copySrcImage, gt, _centreLineImageFileName, out _log);
                    if (GsValueImage.PixelFormat == System.Drawing.Imaging.PixelFormat.Format8bppIndexed)
                        eee.Sheffield.PZ.Imaging.Image.GenerateGraylevelPalette(ref GsValueImage);
                    ShowImage(GsValueImage, "Gs Value of centre lines");
                    Log(_log);
                }
                else
                {
                    _log = "Centre line file is not provided";
                    Log(_log);
                }
            }
            #endregion

            // Techplot output
            if (checkBoxGVF.Checked)
            // GVF techplot output
            {
                OutputGVF(filter, out _log);
                Log(_log);
            }

            #region GVF of centre lines Tecplot output
            if (checkBoxGVFCentreLine.Checked)
            {
                if (_centreLineImageFileName == "")
                {
                    if (openFileDialogCentreLineImageFile.ShowDialog() == DialogResult.OK)
                    {
                        _centreLineImageFileName = openFileDialogCentreLineImageFile.FileName;
                    }
                }
                if (_centreLineImageFileName != "")
                {
                    if (!checkBoxOffset.Checked)
                    // GVF of centre lines
                    {
                        OutputGVFOfCentreLines(filter, _centreLineImageFileName, out _log);
                        Log(_log);
                    }
                    else
                    // GVF of centre lines, offset
                    {
                        int offset = Convert.ToInt32(comboBoxOffset.Text);
                        OutputGVFOfCentreLines(filter, offset, _centreLineImageFileName, out _log);
                        Log(_log);
                    }
                }
                else
                {
                    _log = "Centre line file is not provided";
                    Log(_log);
                }
            }
            #endregion
        }

        private Bitmap DoGsValue(
            GradientVectorFlow filter, Bitmap srcImage, double gt, string centreLineImageFileName, out string logText)
        {
            // thinning and line segments
            //PeterThinning thinningFilter = new PeterThinning();
            ImageDoc thinningImageDoc = new ImageDoc(centreLineImageFileName);
            Bitmap copySrcImage = (Bitmap)thinningImageDoc.Image.Clone();
            eee.Sheffield.PZ.Imaging.Image.StandardizeImageTo8bbpIndexed(ref copySrcImage);
            FreeEndDetector freeEndDetector = new FreeEndDetector();
            TripleJunctionDetector junctionDetector = new TripleJunctionDetector();
            freeEndDetector.ApplyGraylevelImageFilter(copySrcImage);
            junctionDetector.ApplyGraylevelImageFilter(copySrcImage);
            LineSegmentSplitter splitter = new LineSegmentSplitter(freeEndDetector.FreeEndList, junctionDetector.TripleJunctionList);
            splitter.ApplyGraylevelImageFilter(copySrcImage);

            // configurate
            LineSegmentConfiguration c = new LineSegmentConfiguration(splitter.LineSegmentList);
            c.AssignDataTerm(srcImage, filter.U, filter.V, filter.VectorMagnitude);
            eee.Sheffield.PZ.Imaging.ImageFilter.ConvertBitmapMatrix converter = new ConvertBitmapMatrix();
            Bitmap dstImage = converter.ConvertMatrixToGraylevelBitmap(c.DrawGsMatrix(srcImage), true);
            //c.WriteGsFile("gs.txt");
            //c.WritePGFile("pg.txt");
            logText = "Gs value map";

            c.WriteGsHistogram("gsHistogram.txt");
            c.WriteGsListHistogram("gsListHistogram.txt");
            c.WriteAngleHistogram("angleHistogram.txt");
            c.WriteAngleListHistogram("angleListHistogram.txt");

            c.CalculatePC();
            c.WriteCsHistogram("csHistogram.txt");
            c.WritePCHistogram("pcHistogram.txt");
            
            return dstImage;
        } // DoGsValue()

        private void OutputGVF(GradientVectorFlow filter, out string logText)
        {
            filter.WriteGVFTecplotFile("GVFtecplot.dat");
            logText = "GVF Tecplot file saved to \"GVFtecplot.dat\"";
        }

        private void OutputGVFOfCentreLines(GradientVectorFlow filter, string centreLineFileName, out string logText)
        {
            OutputGVFOfCentreLines(filter, 0, centreLineFileName, out logText);
        }
        private void OutputGVFOfCentreLines(GradientVectorFlow filter, int offset, string centreLineFileName, out string logText)
        {
            ImageDoc centreLineImageDoc = new ImageDoc(centreLineFileName);
            Bitmap copySrcImage = (Bitmap)centreLineImageDoc.Image.Clone();
            eee.Sheffield.PZ.Imaging.Image.StandardizeImageTo8bbpIndexed(ref copySrcImage);
            filter.WriteGVFonCentreLineTecplotFile("centreLineGVF.dat", copySrcImage, offset);
            logText = "GVF of centre lines Tecplot file saved to \"centreLineGVF.dat\"";
        }

        private void checkBoxGs_CheckedChanged(object sender, EventArgs e)
        {
            buttonOpenCentreLineImageFile.Visible =  checkBoxGs.Checked;
            label1.Visible = checkBoxGs.Checked;
            textBoxGt.Visible = checkBoxGs.Checked;
        }

        private void checkBoxOffset_CheckedChanged(object sender, EventArgs e)
        {
            comboBoxOffset.Visible = checkBoxOffset.Checked;
        }

        private void buttonOpenCentreLineImageFile_Click(object sender, EventArgs e)
        {
            if (openFileDialogCentreLineImageFile.ShowDialog() == DialogResult.OK)
                _centreLineImageFileName = openFileDialogCentreLineImageFile.FileName;
        }

        private void checkBoxGVFCentreLine_CheckedChanged(object sender, EventArgs e)
        {
            buttonOpenCentreLineImageFile.Visible = checkBoxGVFCentreLine.Checked;
        }

        private void buttonGsHistogram_Click(object sender, EventArgs e)
        {

        }
        #endregion

        
    }
}
